home *** CD-ROM | disk | FTP | other *** search
/ Software Vault: The Gold Collection / Software Vault - The Gold Collection (American Databankers) (1993).ISO / cdr47 / start32.zip / START32.ASM < prev    next >
Assembly Source File  |  1993-04-13  |  25KB  |  924 lines

  1. ; 386 Protected mode control program header.
  2. ; By Tran.
  3. ; Feel free to use this code in your own programs.
  4.  
  5.         .386p
  6.  
  7. EXTMIN  equ     0               ; minimum extended memory needed
  8. TSTAK   equ     400h            ; total stack size (in bytes)
  9. ISTAK   equ     100h            ; hardware IRQ stack size (in bytes)
  10.  
  11. desc    struc
  12. lml     dw      0
  13. bsl     dw      0
  14. bsm     db      0
  15. acc     db      0
  16. lmh     db      0
  17. bsh     db      0
  18. desc    ends
  19.  
  20. task    struc
  21. back            dd      0
  22. esp0            dd      ISTAK
  23. sp0             dd      10h
  24. esp1            dd      ISTAK
  25. sp1             dd      10h
  26. esp2            dd      ISTAK
  27. sp2             dd      10h
  28. ocr3            dd      0
  29. oeip            dd      0
  30. oeflags         dd      0
  31. oeax            dd      0
  32. oecx            dd      0
  33. oedx            dd      0
  34. oebx            dd      0
  35. oesp            dd      0
  36. oebp            dd      0
  37. oesi            dd      0
  38. oedi            dd      0
  39. oes             dd      0
  40. ocs             dd      0
  41. oss             dd      0
  42. ods             dd      0
  43. ofs             dd      0
  44. ogs             dd      0
  45. oldtr           dd      0
  46. iomap           dd      104 shl 16
  47. task    ends
  48.  
  49. stak    segment para stack use16 'stack'
  50. stak    ends
  51. code16  segment para public use16
  52. code16  ends
  53. code32  segment para public use32
  54. code32  ends
  55. codeend segment para public use32
  56. codeend ends
  57.  
  58.  
  59. code16  segment para public use16
  60.         assume cs:code16, ds:code16, ss:code16
  61.         org 0
  62.  
  63. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  64. ; 16 bit basic system data
  65. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  66. stak16  db      100h dup(?)
  67. stak16e label   near
  68. oldint1b        dd      ?
  69. nullint         db      0cfh
  70. errmsg0         db      'You must have a 386 or better to run this program!!!',7,'$'
  71. errmsg1         db      'This system is already in V86 mode!!!',7,'$'
  72. errmsg2         db      'You must have 640k low memory to run this program!!!',7,'$'
  73. errmsg3         db      'Not enough extended memory to run this program!!!',7,'$'
  74. errmsg4         db      'You must have VGA to run this program!!!',7,'$'
  75. defidt          dw      3ffh, 0,0
  76.  
  77. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  78. ; 16 bit basic system code
  79. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  80. ;─────────────────────────────────────────────────────────────────────────────
  81. chek_VGA:                               ; Detect VGA or MCGA card
  82.         xor bx,bx
  83.         mov ax,01a00h
  84.         int 10h
  85.         cmp bl,7
  86.         jb short detectvgano
  87.         cmp bl,0ch
  88.         ja short detectvgano
  89.         ret
  90. detectvgano:
  91.         mov dx,offset errmsg4
  92.         jmp short exit16err
  93. ;─────────────────────────────────────────────────────────────────────────────
  94. chek_processor:                         ; Detect if current processor 386
  95.         pushf
  96.         xor ah,ah
  97.         push ax
  98.         popf
  99.         pushf
  100.         pop ax
  101.         and ah,0f0h
  102.         cmp ah,0f0h
  103.         je short detectno386
  104.         mov ah,0f0h
  105.         push ax
  106.         popf
  107.         pushf
  108.         pop ax
  109.         and ah,0f0h
  110.         jz short detectno386
  111.         popf
  112.         ret
  113. detectno386:
  114.         mov dx,offset errmsg0
  115.         jmp short exit16err
  116. ;─────────────────────────────────────────────────────────────────────────────
  117. chek_virtual:                           ; Chek if already running in V86 mode
  118.         smsw ax
  119.         test al,1
  120.         jnz short detected_virtual86
  121.         ret
  122. detected_virtual86:
  123.         mov dx,offset errmsg1
  124.         jmp short exit16err
  125. ;─────────────────────────────────────────────────────────────────────────────
  126. chek_memory:                            ; Chek and get info on memory
  127.         int 12h
  128.         cmp ax,639
  129.         jb short notenoughlowmem
  130.         movzx eax,ax
  131.         shl eax,10
  132.         sub eax,ds:_code32a
  133.         mov ds:_lomemtop,eax
  134.         mov ah,88h
  135.         int 15h
  136.         cmp ax,EXTMIN
  137.         jb short notenoughhighmem
  138.         mov ds:_totalextmem,ax
  139.         movzx eax,ax
  140.         shl eax,10
  141.         add eax,ds:_himembase
  142.         mov ds:_himemtop,eax
  143.         ret
  144. notenoughlowmem:
  145.         mov dx,offset errmsg2
  146.         jmp short exit16err
  147. notenoughhighmem:
  148.         mov dx,offset errmsg3
  149. ;─────────────────────────────────────────────────────────────────────────────
  150. exit16err:                              ; Exit program with message
  151.         mov ah,9
  152.         int 21h
  153.         mov ax,4cffh
  154.         int 21h
  155. ;═════════════════════════════════════════════════════════════════════════════
  156. start16:                                ; Program begins here
  157.         cli
  158.         mov sp,offset stak16e
  159.         mov ax,cs
  160.         mov ds,ax
  161.         call chek_VGA
  162.         call chek_processor
  163.         call chek_virtual
  164.  
  165.         mov eax,code16                  ; Calc misc memory pointers
  166.         shl eax,4
  167.         mov ds:_code16a,eax
  168.         mov eax,code32
  169.         shl eax,4
  170.         mov ds:_code32a,eax
  171.         mov ebx,codeend
  172.         shl ebx,4
  173.         sub ebx,eax
  174.         add ds:v86task.esp0,ebx
  175.         add ebx,TSTAK
  176.         mov ds:_lomembase,ebx
  177.         mov ebx,100000h
  178.         sub ebx,eax
  179.         mov ds:_himembase,ebx
  180.         call chek_memory
  181.  
  182.         xor ax,ax                       ; Disable CTRL+BREAK
  183.         mov es,ax
  184.         mov eax,es:[1bh*4]
  185.         mov oldint1b,eax
  186.         mov word ptr es:[1bh*4],offset nullint
  187.         mov word ptr es:[1bh*4+2],cs
  188.  
  189.         mov eax,ds:_code32a             ; Set up protected mode adresses
  190.         add dword ptr ds:gdt32a[2],eax
  191.         add dword ptr ds:idt32a[2],eax
  192.         mov ds:code32dsc.bsl,ax
  193.         mov ds:data32dsc.bsl,ax
  194.         add ds:v86taskdsc.bsl,ax
  195.         shr eax,8
  196.         mov ds:code32dsc.bsm,ah
  197.         mov ds:data32dsc.bsm,ah
  198.         add ds:v86taskdsc.bsm,ah
  199.         mov eax,ds:_code16a
  200.         mov ds:retrealc.bsl,ax
  201.         mov ds:retreald.bsl,ax
  202.         shr eax,8
  203.         mov ds:retrealc.bsm,ah
  204.         mov ds:retreald.bsm,ah
  205.  
  206.         lgdt fword ptr ds:gdt32a        ; Init protected mode
  207.         mov eax,cr0
  208.         or al,1
  209.         mov cr0,eax
  210.         db 0eah
  211.         dw start32,8
  212.  
  213. ;═════════════════════════════════════════════════════════════════════════════
  214. v86sys:                                 ; V86 interrupt
  215.         xor eax,eax
  216.         xor ebx,ebx
  217.         xor ecx,ecx
  218.         xor edx,edx
  219.         xor esi,esi
  220.         xor edi,edi
  221.         xor ebp,ebp
  222.         mov ax,cs:v86r_ax
  223.         mov bx,cs:v86r_bx
  224.         mov cx,cs:v86r_cx
  225.         mov dx,cs:v86r_dx
  226.         mov si,cs:v86r_si
  227.         mov di,cs:v86r_di
  228.         mov bp,cs:v86r_bp
  229.         db 0cdh
  230. v86sysintnum    db      ?
  231.         mov cs:v86r_ax,ax
  232.         mov cs:v86r_bx,bx
  233.         mov cs:v86r_cx,cx
  234.         mov cs:v86r_dx,dx
  235.         mov cs:v86r_si,si
  236.         mov cs:v86r_di,di
  237.         mov cs:v86r_bp,bp
  238.         mov cs:v86r_ds,ds
  239.         mov cs:v86r_es,es
  240.         pushf
  241.         pop ax
  242.         mov cs:v86r_flags,ax
  243.         int 0fdh
  244.  
  245. ;═════════════════════════════════════════════════════════════════════════════
  246. prerealmode:                            ; 16 bit protected mode to real mode
  247.         lidt fword ptr defidt
  248.         mov eax,cr0
  249.         and al,0feh
  250.         mov cr0,eax
  251.         db 0eah
  252.         dw realmode,code16
  253. realmode:                               ; Back in real mode
  254.         xor ax,ax                       ; Reenable CTRL+BREAK
  255.         mov es,ax
  256.         mov eax,cs:oldint1b
  257.         mov es:[1bh*4],eax
  258.         mov ax,cs                       ; Fix up regs and quit to DOS
  259.         mov ds,ax
  260.         mov es,ax
  261.         mov ss,ax
  262.         xor eax,eax
  263.         mov fs,ax
  264.         mov gs,ax
  265.         xor ebx,ebx
  266.         xor ecx,ecx
  267.         xor edx,edx
  268.         xor esi,esi
  269.         xor edi,edi
  270.         xor ebp,ebp
  271.         mov esp,offset stak16e+200h
  272.         mov ax,4c00h
  273.         int 21h
  274.  
  275.  
  276. code16  ends
  277.  
  278.  
  279. code32  segment para public use32
  280.         assume cs:code32, ds:code32, ss:code32
  281.         org 0
  282.  
  283. extrn   _main:near
  284.  
  285. public  v86r_ax, v86r_bx, v86r_cx, v86r_dx, v86r_si, v86r_di, v86r_bp
  286. public  v86r_ds, v86r_es, v86r_flags, v86r_ah, v86r_al, v86r_bh, v86r_bl
  287. public  v86r_ch, v86r_cl, v86r_dh, v86r_dl
  288. public  _totalextmem, _code16a, _code32a, _hextbl, _lomembase, _lomemtop
  289. public  _himembase, _himemtop
  290.  
  291. public  _putdosmsg, _getvect, _setvect, _exit, _getmem, _getlomem, _gethimem
  292. public  _lomemsize, _himemsize, _ret
  293.  
  294. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  295. ; 32 bit basic system data
  296. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  297. gdt32           desc    <>
  298. code32dsc       desc    <0ffffh, 0, 0, 10011010b, 11001111b, 0>
  299. data32dsc       desc    <0ffffh, 0, 0, 10010010b, 11001111b, 0>
  300. zerodsc         desc    <0ffffh, 0, 0, 10010010b, 11001111b, 0>
  301. v86taskdsc      desc    <232, v86task, 0, 10001001b, 0, 0>
  302. retrealc        desc    <0ffffh, 0, 0, 10011010b, 0, 0>
  303. retreald        desc    <0ffffh, 0, 0, 10010010b, 0, 0>
  304. idt32           dw      exc0, 8, 08e00h, 0
  305.                 dw      exc1, 8, 08e00h, 0
  306.                 dw      exc2, 8, 08e00h, 0
  307.                 dw      exc3, 8, 08e00h, 0
  308.                 dw      exc4, 8, 08e00h, 0
  309.                 dw      exc5, 8, 08e00h, 0
  310.                 dw      exc6, 8, 08e00h, 0
  311.                 dw      exc7, 8, 08e00h, 0
  312.                 dw      exc8, 8, 08e00h, 0
  313.                 dw      exc9, 8, 08e00h, 0
  314.                 dw      exca, 8, 08e00h, 0
  315.                 dw      excb, 8, 08e00h, 0
  316.                 dw      excc, 8, 08e00h, 0
  317.                 dw      v86gen, 8, 08e00h, 0
  318.                 dw      exce, 8, 08e00h, 0
  319.                 dw      17 dup(unexp, 8, 08e00h, 0)
  320.                 dw      irq0, 8, 08e00h, 0
  321.                 dw      irq1, 8, 08e00h, 0
  322.                 dw      irq2, 8, 08e00h, 0
  323.                 dw      irq3, 8, 08e00h, 0
  324.                 dw      irq4, 8, 08e00h, 0
  325.                 dw      irq5, 8, 08e00h, 0
  326.                 dw      irq6, 8, 08e00h, 0
  327.                 dw      irq7, 8, 08e00h, 0
  328.                 dw      irq8, 8, 08e00h, 0
  329.                 dw      irq9, 8, 08e00h, 0
  330.                 dw      irqa, 8, 08e00h, 0
  331.                 dw      irqb, 8, 08e00h, 0
  332.                 dw      irqc, 8, 08e00h, 0
  333.                 dw      irqd, 8, 08e00h, 0
  334.                 dw      irqe, 8, 08e00h, 0
  335.                 dw      irqf, 8, 08e00h, 0
  336.                 dw      callv86sys, 8, 8e00h, 0
  337. gdt32a          dw      037h, gdt32,0
  338. idt32a          dw      187h, idt32,0
  339. v86task         task    <>
  340.                 db      128 dup(0)
  341.  
  342. v86irqnum       db      ?               ; num of IRQ that ocurred in V86 mode
  343. v86sesp         dd      ?               ; saved ESP during V86 int
  344. v86r_ax         label   word            ; Virtual regs for virtual ints
  345. v86r_al         db      ?
  346. v86r_ah         db      ?
  347. v86r_bx         label   word
  348. v86r_bl         db      ?
  349. v86r_bh         db      ?
  350. v86r_cx         label   word
  351. v86r_cl         db      ?
  352. v86r_ch         db      ?
  353. v86r_dx         label   word
  354. v86r_dl         db      ?
  355. v86r_dh         db      ?
  356. v86r_si         dw      ?
  357. v86r_di         dw      ?
  358. v86r_bp         dw      ?
  359. v86r_ds         dw      ?
  360. v86r_es         dw      ?
  361. v86r_flags      dw      ?
  362.  
  363. oirqm21         db      ?               ; old low IRQ mask
  364. oirqma1         db      ?               ; old high IRQ mask
  365. _totalextmem    dw      ?               ; total extended memory present
  366. _code16a        dd      ?               ; offset of start of program from 0
  367. _code32a        dd      ?               ; offset of start of 32bit code from 0
  368. _lomembase      dd      ?               ; low mem base for allocation
  369. _lomemtop       dd      ?               ; top of low mem
  370. _himembase      dd      ?               ; high mem base for allocation
  371. _himemtop       dd      ?               ; top of high mem
  372. _hextbl         db      '0123456789ABCDEF'
  373.  
  374. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  375. ; 32 bit basic system code
  376. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  377. ;─────────────────────────────────────────────────────────────────────────────
  378. callv86sys:                             ; V86 INT AL
  379.         pushad
  380.         push es
  381.         push fs
  382.         push gs
  383.         mov bx,18h
  384.         mov es,bx
  385.         mov ebx,_code16a
  386.         mov es:v86sysintnum[ebx],al
  387.         mov v86sesp,esp
  388.         xor eax,eax
  389.         push eax
  390.         push eax
  391.         mov ax,v86r_ds
  392.         push eax
  393.         mov ax,v86r_es
  394.         push eax
  395.         mov ebx,code16
  396.         push ebx
  397.         mov eax,offset stak16e
  398.         push eax
  399.         pushfd
  400.         pop eax
  401.         or eax,20000h
  402.         push eax
  403.         push ebx
  404.         mov eax,offset v86sys
  405.         push eax
  406.         iretd
  407. retfromv86:
  408.         mov ax,10h
  409.         mov ds,ax
  410.         mov esp,v86sesp
  411.         pop gs
  412.         pop fs
  413.         pop es
  414.         popad
  415.         iretd
  416. ;─────────────────────────────────────────────────────────────────────────────
  417. v86gen:                                 ; General protection violation handler
  418.         test byte ptr [esp+14],2
  419.         jnz short v86genv86
  420.         pushad
  421.         mov dl,13
  422.         jmp exc
  423. v86genv86:
  424.         add esp,4
  425.         pushad
  426.         mov ax,18h
  427.         mov ds,ax
  428.         movzx ebx,word ptr [esp+36]
  429.         shl ebx,4
  430.         add ebx,[esp+32]
  431.         inc word ptr [esp+32]
  432.         mov al,[ebx]
  433.         mov dl,3
  434.         cmp al,0cch
  435.         je short v86int
  436.         cmp al,0ceh
  437.         ja exc
  438.         je short v86genv86ni
  439.         inc word ptr [esp+32]
  440.         mov dl,[ebx+1]
  441.         cmp dl,0fdh
  442.         jne short v86int
  443.         jmp retfromv86
  444. v86genv86ni:
  445.         mov dl,4
  446. v86int:                                 ; Do interrupt for V86 task
  447.         mov ax,18h
  448.         mov ds,ax
  449.         movzx ebx,dl
  450.         shl ebx,2
  451.         movzx edx,word ptr [esp+48]
  452.         shl edx,4
  453.         sub word ptr [esp+44],6
  454.         add edx,[esp+44]
  455.         mov ax,[esp+40]
  456.         mov [edx+4],ax
  457.         mov ax,[esp+36]
  458.         mov [edx+2],ax
  459.         mov ax,[esp+32]
  460.         mov [edx],ax
  461.         and word ptr [esp+40],0fcffh
  462.         mov eax,ds:[ebx]
  463.         mov [esp+32],ax
  464.         shr eax,16
  465.         mov [esp+36],ax
  466.         popad
  467.         iretd
  468.  
  469. ;─────────────────────────────────────────────────────────────────────────────
  470. exc0:                                   ; Exceptions
  471.         pushad
  472.         mov dl,0
  473.         jmp short exc
  474. exc1:
  475.         pushad
  476.         mov dl,1
  477.         jmp short exc
  478. exc2:
  479.         pushad
  480.         mov dl,2
  481.         jmp short exc
  482. exc3:
  483.         pushad
  484.         mov dl,3
  485.         jmp short exc
  486. exc4:
  487.         pushad
  488.         mov dl,4
  489.         jmp short exc
  490. exc5:
  491.         pushad
  492.         mov dl,5
  493.         jmp short exc
  494. exc6:
  495.         pushad
  496.         mov dl,6
  497.         jmp short exc
  498. exc7:
  499.         pushad
  500.         mov dl,7
  501.         jmp short exc
  502. exc8:
  503.         pushad
  504.         mov dl,8
  505.         jmp short exc
  506. exc9:
  507.         pushad
  508.         mov dl,9
  509.         jmp short exc
  510. exca:
  511.         pushad
  512.         mov dl,10
  513.         jmp short exc
  514. excb:
  515.         pushad
  516.         mov dl,11
  517.         jmp short exc
  518. excc:
  519.         pushad
  520.         mov dl,12
  521.         jmp short exc
  522. exce:
  523.         pushad
  524.         mov dl,14
  525.         jmp short exc
  526. unexp:                                  ; Unexpected interrupt
  527.         pushad
  528.         mov dl,0ffh
  529. exc:
  530.         cld                             ; Dump data
  531.         mov ax,10h
  532.         mov ds,ax
  533.         mov es,ax
  534.         mov fs,ax
  535.         mov ax,18h
  536.         mov gs,ax
  537.         mov al,0ffh
  538.         out 21h,al
  539.         out 0a1h,al
  540.         mov al,10h
  541.         mov v86r_ax,3
  542.         int 30h
  543.         mov edi,0b8000h+2*160
  544.         sub edi,_code32a
  545.         mov ebx,offset _hextbl
  546.         mov ecx,2
  547.         shl edx,24
  548.         mov ah,0fh
  549.         call excput
  550.         add edi,152
  551.         mov ah,0ah
  552.         mov ebp,8
  553. excl0:
  554.         pop edx
  555.         mov cl,8
  556.         call excput
  557.         dec ebp
  558.         jnz excl0
  559.         mov ebp,offset ds:stak32+ISTAK
  560.         cmp esp,ebp
  561.         jb short excf0
  562.         mov ebp,offset ds:stak32+TSTAK
  563. excf0:
  564.         mov ah,0ch
  565. excl1:
  566.         pop edx
  567.         mov cl,8
  568.         call excput
  569.         cmp esp,ebp
  570.         jbe excf0
  571.         jmp _exit
  572. excput:
  573.         rol edx,4
  574.         mov al,dl
  575.         and al,0fh
  576.         xlat
  577.         stosw
  578.         loop excput
  579.         mov al,' '
  580.         stosw
  581.         stosw
  582.         ret
  583.  
  584. ;─────────────────────────────────────────────────────────────────────────────
  585. irq0:                                   ; Do IRQs
  586.         push ax
  587.         mov al,8
  588.         jmp short irq
  589. irq1:
  590.         push ax
  591.         mov al,9
  592.         jmp short irq
  593. irq2:
  594.         push ax
  595.         mov al,0ah
  596.         jmp short irq
  597. irq3:
  598.         push ax
  599.         mov al,0bh
  600.         jmp short irq
  601. irq4:
  602.         push ax
  603.         mov al,0ch
  604.         jmp short irq
  605. irq5:
  606.         push ax
  607.         mov al,0dh
  608.         jmp short irq
  609. irq6:
  610.         push ax
  611.         mov al,0eh
  612.         jmp short irq
  613. irq7:
  614.         push ax
  615.         mov al,0fh
  616.         jmp short irq
  617. irq8:
  618.         push ax
  619.         mov al,70h
  620.         jmp short irq
  621. irq9:
  622.         push ax
  623.         mov al,71h
  624.         jmp short irq
  625. irqa:
  626.         push ax
  627.         mov al,72h
  628.         jmp short irq
  629. irqb:
  630.         push ax
  631.         mov al,73h
  632.         jmp short irq
  633. irqc:
  634.         push ax
  635.         mov al,74h
  636.         jmp short irq
  637. irqd:
  638.         push ax
  639.         mov al,75h
  640.         jmp short irq
  641. irqe:
  642.         push ax
  643.         mov al,76h
  644.         jmp short irq
  645. irqf:
  646.         push ax
  647.         mov al,77h
  648. irq:
  649.         test byte ptr [esp+12],2
  650.         jnz short v86irq
  651.         push ds                         ; A real mode IRQ in protected mode
  652.         push ss
  653.         pop ds
  654.         int 30h
  655.         pop ds
  656.         pop ax
  657.         iretd
  658. v86irq:                                 ; An IRQ from V86 mode
  659.         mov ss:v86irqnum,al
  660.         pop ax
  661.         pushad
  662.         mov dl,ss:v86irqnum
  663.         jmp v86int
  664.  
  665. ;─────────────────────────────────────────────────────────────────────────────
  666. set8529vektorz:                         ; Set new IRQ vektor numbers
  667.         mov al,11h                      ;  BL - low vektor base #
  668.         out 20h,al                      ;  BH - high vektor base #
  669.         jmp short $+2
  670.         mov al,bl
  671.         out 21h,al
  672.         jmp short $+2
  673.         mov al,4h
  674.         out 21h,al
  675.         jmp short $+2
  676.         mov al,1h
  677.         out 21h,al
  678.         jmp short $+2
  679.         mov al,11h
  680.         out 0a0h,al
  681.         jmp short $+2
  682.         mov al,bh
  683.         out 0a1h,al
  684.         jmp short $+2
  685.         mov al,2h
  686.         out 0a1h,al
  687.         jmp short $+2
  688.         mov al,1h
  689.         out 0a1h,al
  690.         jmp short $+2
  691.         mov al,0ffh
  692.         out 0a1h,al
  693.         ret
  694.  
  695. ;─────────────────────────────────────────────────────────────────────────────
  696. enableA20:                              ; Enable gate A20
  697.         call enableA20o1
  698.         jnz short enableA20done
  699.         mov al,0d1h
  700.         out 64h,al
  701.         call enableA20o1
  702.         jnz short enableA20done
  703.         mov al,0b7h
  704.         call enableA20o2
  705.         and al,0ch
  706.         or al,0d3h
  707.         out 60h,al
  708.         call enableA20o1
  709. enableA20done:
  710.         ret
  711. enableA20o1:
  712.         mov ecx,20000h
  713. enableA20o1l:
  714.         jmp short $+2
  715.         in al,64h
  716.         test al,2
  717.         loopnz enableA20o1l
  718.         ret
  719. enableA20o2:
  720.         out 70h,al
  721.         jmp short $+2
  722.         jmp short $+2
  723.         in al,71h
  724.         ret
  725.  
  726. ;═════════════════════════════════════════════════════════════════════════════
  727. start32:                                ; 32bit code begins here
  728.         lidt fword ptr cs:idt32a
  729.         mov ax,10h
  730.         mov ds,ax
  731.         mov es,ax
  732.         mov fs,ax
  733.         mov ss,ax
  734.         mov ax,18h
  735.         mov gs,ax
  736.         mov esp,_lomembase
  737.         mov ax,20h
  738.         ltr ax
  739.         pushfd
  740.         pop eax
  741.         or ah,30h
  742.         and ah,not 40h
  743.         push eax
  744.         popfd
  745.         in al,21h
  746.         mov oirqm21,al
  747.         or al,3
  748.         out 21h,al
  749.         in al,0a1h
  750.         mov oirqma1,al
  751.         mov bx,2820h
  752.         call set8529vektorz
  753.         call enableA20
  754.         sti
  755.         jmp _main
  756.  
  757. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  758. ; Some 'system' services
  759. ;▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
  760.  
  761. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  762. ; Exit to real mode
  763. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  764. _exit:
  765.         cli
  766.         mov bx,7008h
  767.         call set8529vektorz
  768.         mov al,oirqm21
  769.         out 21h,al
  770.         mov al,oirqma1
  771.         out 0a1h,al
  772.         mov ax,30h
  773.         mov ds,ax
  774.         mov es,ax
  775.         mov fs,ax
  776.         mov gs,ax
  777.         mov ss,ax
  778.         db 0eah
  779.         dw prerealmode,0,28h
  780.  
  781. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  782. ; Get interrupt vektor (0-30h)
  783. ; In:
  784. ;   BL - interrupt number
  785. ; Out:
  786. ;   EAX - 32 bit offset in code
  787. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  788. _getvect:
  789.         push ebx
  790.         movzx ebx,bl
  791.         mov ax,idt32[ebx*8+6]
  792.         shl eax,16
  793.         mov ax,idt32[ebx*8]
  794.         pop ebx
  795. _ret:                                   ; Generic RET for all procedures
  796.         ret
  797.  
  798. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  799. ; Set interrupt vektor (0-30h)
  800. ; In:
  801. ;   BL - interrupt number
  802. ;   EAX - 32 bit offset in code
  803. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  804. _setvect:
  805.         pushf
  806.         cli
  807.         push eax
  808.         push ebx
  809.         movzx ebx,bl
  810.         mov idt32[ebx*8],ax
  811.         shr eax,16
  812.         mov idt32[ebx*8+6],ax
  813.         pop ebx
  814.         pop eax
  815.         popf
  816.         ret
  817.  
  818. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  819. ; Allocate any mem, (first cheks low, then high)
  820. ; In:
  821. ;   EAX - size requested
  822. ; Out:
  823. ;   CF=1  - not enough mem
  824. ;     EAX - ?
  825. ;   CF=0  - memory allocated
  826. ;     EAX - linear pointer to mem
  827. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  828. _getmem:
  829.         push eax
  830.         call _getlomem
  831.         pop eax
  832.         jnc _ret
  833.         jmp short _gethimem
  834.  
  835. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  836. ; Allocate some low mem
  837. ; In:
  838. ;   EAX - size requested
  839. ; Out:
  840. ;   CF=1  - not enough mem
  841. ;     EAX - ?
  842. ;   CF=0  - memory allocated
  843. ;     EAX - linear pointer to mem
  844. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  845. _getlomem:
  846.         add eax,_lomembase
  847.         cmp eax,_lomemtop
  848.         ja short getmemerr
  849.         xchg eax,_lomembase
  850.         clc
  851.         ret
  852. getmemerr:
  853.         stc
  854.         ret
  855.  
  856. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  857. ; Allocate some high mem
  858. ; In:
  859. ;   EAX - size requested
  860. ; Out:
  861. ;   CF=1  - not enough mem
  862. ;     EAX - ?
  863. ;   CF=0  - memory allocated
  864. ;     EAX - linear pointer to mem
  865. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  866. _gethimem:
  867.         add eax,_himembase
  868.         cmp eax,_himemtop
  869.         ja short getmemerr
  870.         xchg eax,_himembase
  871.         clc
  872.         ret
  873.  
  874. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  875. ; Get amount of free low mem
  876. ; Out:
  877. ;   EAX - number of bytes free
  878. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  879. _lomemsize:
  880.         mov eax,_lomemtop
  881.         sub eax,_lomembase
  882.         ret
  883.  
  884. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  885. ; Get amount of free high mem
  886. ; Out:
  887. ;   EAX - number of bytes free
  888. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  889. _himemsize:
  890.         mov eax,_himemtop
  891.         sub eax,_himembase
  892.         ret
  893.  
  894. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  895. ; Put '$' terminated message to DOS
  896. ; In:
  897. ;   EDX -> message in low mem
  898. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  899. _putdosmsg:
  900.         push ax
  901.         push edx
  902.         add edx,_code32a
  903.         mov al,dl
  904.         and ax,0fh
  905.         shr edx,4
  906.         mov v86r_ds,dx
  907.         mov v86r_dx,ax
  908.         mov v86r_ah,9
  909.         mov al,21h
  910.         int 30h
  911.         pop edx
  912.         pop ax
  913.         ret
  914.  
  915. code32  ends
  916.  
  917.  
  918. codeend segment para public use32
  919.         assume cs:codeend
  920. stak32  label   near
  921. codeend ends
  922.         end     start16
  923.  
  924.